package com.gl.basis.common.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;

import com.gl.basis.common.constant.ResultCode;
import com.gl.basis.common.exception.BusinessException;


public class BeanUtil {

	/** 自定义日期转换器 **/
	private static final Converter dateConverter;
	/** 自定义数值转换器 **/
	private static final Converter bigDecimalConverter;

	static {
		dateConverter = new Converter() {
			@SuppressWarnings("rawtypes")
			public Object convert(Class type,
					Object value) {
				try {
					if (value != null) {
						if (value instanceof Long) {
							return DateUtils.parse((long) value);
						} else if (value instanceof String) {
							return DateUtils.parse(String.valueOf(value), "yyyy-MM-dd HH:mm:ss");
						} else {
							return (value instanceof Date) ? (Date) value : null;
						}
					} else {
						return null;
					}
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println("transMap2Bean2 Error " + e);
				}

				return null;
			}
		};

		bigDecimalConverter = new Converter() {
			@SuppressWarnings("rawtypes")
			public Object convert(Class type,
					Object value) {
				try {
					if (value != null) {
						if (value instanceof Integer) {
							return new BigDecimal((Integer) value);
						} else if (value instanceof Double) {
							return new BigDecimal((Double) value).setScale(2, BigDecimal.ROUND_HALF_UP);
						} else if (value instanceof String) {
							return new BigDecimal(String.valueOf(value)).setScale(2, BigDecimal.ROUND_HALF_UP);
						} else {
							return (value instanceof BigDecimal) ? (BigDecimal) value : null;
						}
					} else {
						return null;
					}
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println("transMap2Bean2 Error " + e);
				}

				return null;
			}
		};
		ConvertUtils.register(dateConverter, java.util.Date.class);
		ConvertUtils.register(bigDecimalConverter, BigDecimal.class);
	}

	// Map --> Bean 2: 利用org.apache.commons.beanutils 工具类实现 Map --> Bean
	public static void transMap2Bean2(Map<String, Object> map,
			Object obj) {
		if (map == null || obj == null) {
			return;
		}
		try {
			BeanUtils.populate(obj, map);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("transMap2Bean2 Error " + e);
		}
	}

	// Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
	/*public static void transMap2Bean(Map<String, Object> map, Object obj) {  

		try {  
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());  
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  

			for (PropertyDescriptor property : propertyDescriptors) {  
				String key = property.getName();  

				if (map.containsKey(key)) {  
					Object value = map.get(key);  
					// 得到property对应的setter方法  
					Method setter = property.getWriteMethod();
					
					if(key.lastIndexOf("Date") != -1) {
						if(value instanceof Long) {
							setter.invoke(obj, new Date((long)value));
						}
						if(value instanceof String) {
							setter.invoke(obj, DateUtils.parse((String)value, "yyyy-MM-dd HH:mm:ss"));
						}
					}else {
						setter.invoke(obj, value);  
					}
				}  

			}  

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("transMap2Bean Error " + e);  
		}  

		return;  

	}  */

	/**
	 * Bean转Map
	 * 
	 * @Title: transBean2Map
	 * @param @param obj
	 * @param @param filterNullValue 是否过滤Value为Null的键值对
	 * @param @param vClass 转换后Value的类型
	 * @param @return 参数
	 * @return Map<String,V> 返回类型
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	public static <V> Map<String, V> transBean2Map(Object obj,
			boolean filterNullValue,
			Class<V> vClass) {
		if (obj == null) {
			return null;
		}
		Map<String, V> map = new HashMap<String, V>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();

				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					V value = (V) getter.invoke(obj);

					if (!filterNullValue || (value != null&&!"null".equals(value)))
						map.put(key, value);
				}

			}
		} catch (Exception e) {
			System.out.println("transBean2Map Error " + e);
		}

		return map;

	}

	/**
	 * @Title: transBean2Map
	 * @param @param obj
	 * @param @param filterNullValue 是否过滤Value为Null的键值对
	 * @param @return 参数
	 * @return Map<String,Object> 返回类型
	 * @throws
	 */
	public static Map<String, Object> transBean2Map(Object obj,
			boolean filterNullValue) {
		return transBean2Map(obj, filterNullValue, Object.class);
	}

	// Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
	public static Map<String, Object> transBean2Map(Object obj) {
		return transBean2Map(obj, false);
	}

	public static void copyProperties(Object dest,
			Object orig) {
		try {
			ConvertUtils.register(dateConverter, java.util.Date.class);
			ConvertUtils.register(bigDecimalConverter, BigDecimal.class);
			BeanUtils.copyProperties(dest, orig);
		} catch (IllegalAccessException | InvocationTargetException e) {
			throw new BusinessException(ResultCode.INTERNAL_SERVER_ERROR.getMsg(), ResultCode.INTERNAL_SERVER_ERROR.getCode(), e);
		}
	}

}
